vtd: Add a boot parameter option for snoop control capability for VT-d.
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 4 Feb 2009 12:00:06 +0000 (12:00 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 4 Feb 2009 12:00:06 +0000 (12:00 +0000)
The default is to use snoop control.

Signed-off-by: Xin, Xiaohui <xiaohui.xin@intel.com>
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/vtd/dmar.c

index f8bde43f62c143471d866058b2d840191dd82e94..715b103123971580608b3737183dc7978a325405 100644 (file)
@@ -33,6 +33,8 @@ int amd_iov_detect(void);
  *   no-pv                      Disable IOMMU for PV domains (default)
  *   force|required             Don't boot unless IOMMU is enabled
  *   passthrough                Bypass VT-d translation for Dom0
+ *   snoop                      Utilize the snoop control for IOMMU (default)
+ *   no-snoop                   Dont utilize the snoop control for IOMMU
  */
 custom_param("iommu", parse_iommu_param);
 int iommu_enabled = 0;
@@ -45,6 +47,7 @@ static void __init parse_iommu_param(char *s)
 {
     char *ss;
     iommu_enabled = 1;
+    iommu_snoop = 1;
 
     do {
         ss = strchr(s, ',');
@@ -62,6 +65,10 @@ static void __init parse_iommu_param(char *s)
             force_iommu = 1;
         else if ( !strcmp(s, "passthrough") )
             iommu_passthrough = 1;
+        else if ( !strcmp(s, "snoop") )
+            iommu_snoop = 1;
+        else if ( !strcmp(s, "no-snoop") )
+            iommu_snoop = 0;
 
         s = ss + 1;
     } while ( ss );
index efd197fe7516c03b0617728593476ef9c358828d..8df7b006cd4dbd59761375465b87b24308812e97 100644 (file)
@@ -540,13 +540,15 @@ int acpi_dmar_init(void)
     /* Giving that all devices within guest use same io page table,
      * enable snoop control only if all VT-d engines support it.
      */
-    iommu_snoop = 1;
-    for_each_drhd_unit ( drhd )
+    if ( iommu_snoop )
     {
-        iommu = drhd->iommu;
-        if ( !ecap_snp_ctl(iommu->ecap) ) {
-            iommu_snoop = 0;
-            break;
+        for_each_drhd_unit ( drhd )
+        {
+            iommu = drhd->iommu;
+            if ( !ecap_snp_ctl(iommu->ecap) ) {
+                iommu_snoop = 0;
+                break;
+            }
         }
     }